import os
import robocasa

BASE_ASSET_ZOO_PATH = os.path.join(robocasa.models.assets_root, "objects")


# Constant that contains information about each object category. These will be used to generate the ObjCat classes for each category
OBJ_CATEGORIES = dict(
    liquor=dict(
        types=("drink", "alcohol"),
        graspable=True,
        washable=False,
        microwavable=False,
        cookable=False,
        freezable=False,
        aigen=dict(
            model_folders=["aigen_objs/alcohol"],
            scale=1.50,
        ),
        objaverse=dict(
            model_folders=["objaverse/alcohol"],
            scale=1.35,
        ),
    ),
    apple=dict(
        types=("fruit"),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=True,
        freezable=False,
        aigen=dict(
            scale=1.0,
        ),
        objaverse=dict(
            scale=0.90,
        ),
    ),
    avocado=dict(
        types=("vegetable"),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=False,
        aigen=dict(
            scale=0.90,
        ),
        objaverse=dict(
            scale=0.90,
        ),
    ),
    bagel=dict(
        types=("bread_food"),
        graspable=False,
        washable=False,
        microwavable=False,
        cookable=False,
        freezable=False,
        aigen=dict(
            scale=1.2,
        ),
        objaverse=dict(
            exclude=[
                "bagel_8",
            ],
        ),
    ),
    bagged_food=dict(
        types=("packaged_food"),
        graspable=False,
        washable=False,
        microwavable=False,
        cookable=False,
        freezable=True,
        aigen=dict(
            scale=1.1,
        ),
        objaverse=dict(
            exclude=[
                "bagged_food_12",
            ],
        ),
    ),
    baguette=dict(
        types=("bread_food"),
        graspable=True,
        washable=False,
        microwavable=False,
        cookable=False,
        freezable=True,
        aigen=dict(
            scale=1.35,
        ),
        objaverse=dict(
            exclude=[
                "baguette_3",  # small holes on ends
            ],
        ),
    ),
    banana=dict(
        types=("fruit"),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=False,
        aigen=dict(
            scale=1.10,
        ),
        objaverse=dict(
            scale=0.95,
        ),
    ),
    bar=dict(
        types=("packaged_food"),
        graspable=True,
        washable=False,
        microwavable=False,
        cookable=False,
        freezable=True,
        aigen=dict(
            scale=[1.25, 1.25, 1.75],
        ),
        objaverse=dict(
            scale=[0.75, 0.75, 1.2],
            exclude=[
                "bar_1",  # small holes scattered
            ],
        ),
    ),
    bar_soap=dict(
        types=("cleaner"),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=False,
        aigen=dict(
            scale=[1.25, 1.25, 1.40],
        ),
        objaverse=dict(
            scale=[0.95, 0.95, 1.05],
            exclude=["bar_soap_2"],
        ),
    ),
    beer=dict(
        types=("drink", "alcohol"),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=False,
        aigen=dict(
            scale=1.30,
        ),
        objaverse=dict(scale=1.15),
    ),
    bell_pepper=dict(
        types=("vegetable"),
        graspable=True,
        washable=True,
        microwavable=True,
        cookable=True,
        freezable=True,
        aigen=dict(
            scale=1.0,
        ),
        objaverse=dict(
            scale=0.75,
        ),
    ),
    bottled_drink=dict(
        types=("drink"),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=True,
        aigen=dict(
            scale=1.25,
        ),
        objaverse=dict(),
    ),
    bottled_water=dict(
        types=("drink"),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=True,
        aigen=dict(
            scale=1.30,
        ),
        objaverse=dict(
            scale=1.10,
            exclude=[
                "bottled_water_0",  # minor hole at top
                "bottled_water_5",  # causing error. eigenvalues of mesh inertia violate A + B >= C
            ],
        ),
    ),
    bowl=dict(
        types=("receptacle", "stackable"),
        graspable=True,
        washable=True,
        microwavable=True,
        cookable=False,
        freezable=False,
        aigen=dict(
            scale=1.75,
        ),
        objaverse=dict(
            scale=2.0,
            exclude=[
                "bowl_21",  # can see through from bottom of bowl
            ],
        ),
    ),
    boxed_drink=dict(
        types=("drink"),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=True,
        aigen=dict(
            scale=1.1,
        ),
        objaverse=dict(
            scale=0.80,
            exclude=[
                "boxed_drink_9",  # hole on bottom
                "boxed_drink_6",  # hole on bottom
                "boxed_drink_8",  # hole on bottom
            ],
        ),
    ),
    boxed_food=dict(
        types=("packaged_food"),
        graspable=True,
        washable=False,
        microwavable=True,
        cookable=False,
        freezable=True,
        aigen=dict(
            scale=1.25,
        ),
        objaverse=dict(
            scale=1.1,
            exclude=[
                "boxed_food_5",  # causing error. eigenvalues of mesh inertia violate A + B >= C
            ],
            # exclude=[
            #     "boxed_food_5",
            #     "boxed_food_3", "boxed_food_1", "boxed_food_6", "boxed_food_11", "boxed_food_10", "boxed_food_8", "boxed_food_9", "boxed_food_7", "boxed_food_2", # self turning due to single collision geom
            # ],
        ),
    ),
    bread=dict(
        types=("bread_food"),
        graspable=True,
        washable=False,
        microwavable=False,
        cookable=False,
        freezable=True,
        aigen=dict(
            scale=[0.80, 0.80, 1.0],
        ),
        objaverse=dict(scale=[0.70, 0.70, 1.0], exclude=["bread_22"]),  # hole on bottom
    ),
    broccoli=dict(
        types=("vegetable"),
        graspable=True,
        washable=True,
        microwavable=True,
        cookable=True,
        freezable=True,
        aigen=dict(
            scale=1.35,
        ),
        objaverse=dict(
            scale=1.25,
            exclude=[
                "broccoli_2",  # holes on one part
            ],
        ),
    ),
    cake=dict(
        types=("sweets"),
        graspable=True,
        washable=False,
        microwavable=False,
        cookable=False,
        freezable=True,
        aigen=dict(
            scale=0.8,
        ),
        objaverse=dict(
            scale=0.8,
        ),
    ),
    can=dict(
        types=("drink"),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=True,
        aigen=dict(),
        objaverse=dict(
            exclude=[
                "can_10",  # hole on bottom
                "can_5",  # causing error: faces of mesh have inconsistent orientation.
            ],
        ),
    ),
    candle=dict(
        types=("decoration"),
        graspable=True,
        washable=False,
        microwavable=False,
        cookable=False,
        freezable=False,
        aigen=dict(
            scale=1.5,
        ),
        objaverse=dict(
            exclude=[
                "candle_11",  # hole at bottom
                # "candle_2", # can't see from bottom view angle
                # "candle_15", # can't see from bottom view angle
            ],
        ),
    ),
    canned_food=dict(
        types=("packaged_food"),
        graspable=True,
        washable=True,
        microwavable=True,
        cookable=False,
        freezable=True,
        aigen=dict(
            scale=1.15,
        ),
        objaverse=dict(
            scale=0.90,
            exclude=[
                "canned_food_7",  # holes at top and bottom
            ],
        ),
    ),
    carrot=dict(
        types=("vegetable"),
        graspable=True,
        washable=True,
        microwavable=True,
        cookable=True,
        freezable=True,
        aigen=dict(
            scale=1.25,
        ),
        objaverse=dict(),
    ),
    cereal=dict(
        types=("packaged_food"),
        graspable=True,
        washable=False,
        microwavable=False,
        cookable=False,
        freezable=False,
        aigen=dict(
            scale=1.15,
        ),
        objaverse=dict(
            # exclude=[
            #     "cereal_2", "cereal_5", "cereal_13", "cereal_3", "cereal_9", "cereal_0", "cereal_7", "cereal_4", "cereal_8", "cereal_12", "cereal_11", "cereal_1", "cereal_6", "cereal_10", # self turning due to single collision geom
            # ]
        ),
    ),
    cheese=dict(
        types=("dairy"),
        graspable=True,
        washable=True,
        microwavable=True,
        cookable=True,
        freezable=True,
        aigen=dict(
            scale=1.0,
        ),
        objaverse=dict(
            scale=0.85,
        ),
    ),
    chips=dict(
        types=("packaged_food"),
        graspable=False,
        washable=False,
        microwavable=False,
        cookable=False,
        freezable=False,
        aigen=dict(
            scale=1.5,
        ),
        objaverse=dict(
            exclude=[
                "chips_12",  # minor hole at bottom of bag
                # "chips_2", # a weird texture at top/bottom but keeping this
            ]
        ),
    ),
    chocolate=dict(
        types=("sweets"),
        graspable=False,
        washable=False,
        microwavable=False,
        cookable=False,
        freezable=True,
        aigen=dict(
            scale=[1.0, 1.0, 1.35],
        ),
        objaverse=dict(
            scale=[0.80, 0.80, 1.20],
            exclude=[
                # "chocolate_2", # self turning due to single collision geom
            ],
        ),
    ),
    coffee_cup=dict(
        types=("drink"),
        graspable=True,
        washable=False,
        microwavable=True,
        cookable=False,
        freezable=False,
        aigen=dict(
            scale=1.35,
        ),
        objaverse=dict(
            exclude=[
                "coffee_cup_18",  # can see thru top
                "coffee_cup_5",  # can see thru from bottom side
                "coffee_cup_19",  # can see thru from bottom side
            ],
        ),
    ),
    condiment_bottle=dict(
        types=("condiment"),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=False,
        aigen=dict(
            scale=1.35,
            model_folders=["aigen_objs/condiment"],
        ),
        objaverse=dict(
            scale=1.05,
            model_folders=["objaverse/condiment"],
        ),
    ),
    corn=dict(
        types=("vegetable"),
        graspable=True,
        washable=True,
        microwavable=True,
        cookable=True,
        freezable=True,
        aigen=dict(
            scale=1.5,
        ),
        objaverse=dict(scale=1.05),
    ),
    croissant=dict(
        types=("pastry"),
        graspable=True,
        washable=False,
        microwavable=False,
        cookable=False,
        freezable=True,
        aigen=dict(
            scale=0.90,
        ),
        objaverse=dict(
            scale=0.90,
        ),
    ),
    cucumber=dict(
        types=("vegetable"),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=True,
        aigen=dict(
            scale=1.1,
        ),
        objaverse=dict(),
    ),
    cup=dict(
        types=("receptacle", "stackable"),
        graspable=True,
        washable=True,
        microwavable=True,
        cookable=False,
        freezable=False,
        aigen=dict(
            scale=1.35,
        ),
        objaverse=dict(),
    ),
    cupcake=dict(
        types=("sweets"),
        graspable=True,
        washable=False,
        microwavable=False,
        cookable=False,
        freezable=True,
        aigen=dict(
            scale=0.90,
        ),
        objaverse=dict(
            exclude=[
                "cupcake_0",  # can see thru bottom
                "cupcake_10",  # can see thru bottom,
                "cupcake_1",  # very small hole at bottom
            ]
        ),
    ),
    cutting_board=dict(
        types=("receptacle"),
        graspable=False,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=False,
        aigen=dict(
            scale=2.0,
        ),
        objaverse=dict(
            scale=1.35,
            exclude=[
                "cutting_board_14",
                "cutting_board_3",
                "cutting_board_10",
                "cutting_board_6",  # these models still modeled with meshes which should work most of the time, but excluding them for safety
            ],
        ),
    ),
    donut=dict(
        types=("sweets", "pastry"),
        graspable=True,
        washable=False,
        microwavable=False,
        cookable=False,
        freezable=True,
        aigen=dict(
            scale=1.5,
        ),
        objaverse=dict(
            scale=1.15,
        ),
    ),
    egg=dict(
        types=("dairy"),
        graspable=True,
        washable=True,
        microwavable=True,
        cookable=True,
        freezable=True,
        aigen=dict(
            scale=1.15,
        ),
        objaverse=dict(
            scale=0.85,
        ),
    ),
    eggplant=dict(
        types=("vegetable"),
        graspable=True,
        washable=True,
        microwavable=True,
        cookable=True,
        freezable=True,
        aigen=dict(
            scale=1.30,
        ),
        objaverse=dict(scale=0.95),
    ),
    fish=dict(
        types=("meat"),
        graspable=True,
        washable=True,
        microwavable=True,
        cookable=True,
        freezable=True,
        aigen=dict(
            scale=[1.35, 1.35, 2.0],
        ),
        objaverse=dict(
            scale=[1.0, 1.0, 1.5],
        ),
    ),
    fork=dict(
        types=("utensil"),
        graspable=False,
        washable=True,
        microwavable=True,
        cookable=True,
        freezable=False,
        aigen=dict(
            scale=1.75,
        ),
        objaverse=dict(),
    ),
    garlic=dict(
        types=("vegetable"),
        graspable=True,
        washable=True,
        microwavable=True,
        cookable=True,
        freezable=True,
        aigen=dict(
            scale=1.3,
        ),
        objaverse=dict(scale=1.10, exclude=["garlic_3"]),  # has hole on side
    ),
    hot_dog=dict(
        types=("cooked_food"),
        graspable=True,
        washable=False,
        microwavable=True,
        cookable=False,
        freezable=True,
        aigen=dict(
            scale=1.4,
        ),
        objaverse=dict(),
    ),
    jam=dict(
        types=("packaged_food"),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=True,
        aigen=dict(
            scale=1.05,
        ),
        objaverse=dict(
            scale=0.90,
        ),
    ),
    jug=dict(
        types=("receptacle"),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=False,
        aigen=dict(
            scale=1.5,
        ),
        objaverse=dict(
            scale=1.5,
        ),
    ),
    ketchup=dict(
        types=("condiment"),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=False,
        aigen=dict(
            scale=1.35,
        ),
        objaverse=dict(
            exclude=[
                "ketchup_5"  # causing error: faces of mesh have inconsistent orientation.
            ]
        ),
    ),
    kettle_electric=dict(
        types=("receptacle"),
        graspable=True,
        washable=False,
        microwavable=False,
        cookable=False,
        freezable=False,
        objaverse=dict(
            scale=1.35,
            model_folders=["objaverse/kettle"],
            exclude=[
                f"kettle_{i}"
                for i in range(29)
                if i not in [0, 7, 9, 12, 13, 17, 24, 25, 26, 27]
            ],
        ),
        aigen=dict(
            scale=1.5,
            model_folders=["aigen_objs/kettle"],
            exclude=[f"kettle_{i}" for i in range(11) if i not in [0, 2, 6, 9, 10, 11]],
        ),
    ),
    kettle_non_electric=dict(
        types=("receptacle"),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=False,
        objaverse=dict(
            scale=1.35,
            model_folders=["objaverse/kettle"],
            exclude=[
                f"kettle_{i}"
                for i in range(29)
                if i in [0, 7, 9, 12, 13, 17, 24, 25, 26, 27]
            ],
        ),
        aigen=dict(
            scale=1.5,
            model_folders=["aigen_objs/kettle"],
            exclude=[f"kettle_{i}" for i in range(11) if i in [0, 2, 6, 9, 10, 11]],
        ),
    ),
    kiwi=dict(
        types=("fruit"),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=True,
        aigen=dict(
            scale=0.90,
        ),
        objaverse=dict(
            scale=0.90,
        ),
    ),
    knife=dict(
        types=("utensil"),
        graspable=False,
        washable=True,
        microwavable=True,
        cookable=True,
        freezable=False,
        aigen=dict(
            scale=1.35,
        ),
        objaverse=dict(
            scale=1.20,
        ),
    ),
    ladle=dict(
        types=("utensil"),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=True,
        freezable=False,
        aigen=dict(
            scale=1.5,
        ),
        objaverse=dict(
            scale=1.10,
        ),
    ),
    lemon=dict(
        types=("vegetable"),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=True,
        freezable=True,
        aigen=dict(
            scale=1.1,
        ),
        objaverse=dict(),
    ),
    lime=dict(
        types=("vegetable"),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=True,
        freezable=True,
        objaverse=dict(
            scale=1.0,
        ),
        aigen=dict(
            scale=0.90,
        ),
    ),
    mango=dict(
        types=("fruit"),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=True,
        freezable=True,
        aigen=dict(
            scale=1.0,
        ),
        objaverse=dict(
            scale=0.85,
            exclude=[
                "mango_3",  # one half is pitch dark
            ],
        ),
    ),
    milk=dict(
        types=("dairy", "drink"),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=False,
        aigen=dict(
            scale=1.35,
        ),
        objaverse=dict(
            exclude=[
                "milk_6"  # causing error: eigenvalues of mesh inertia violate A + B >= C
            ]
        ),
    ),
    mug=dict(
        types=("receptacle", "stackable"),
        graspable=True,
        washable=True,
        microwavable=True,
        cookable=False,
        freezable=False,
        aigen=dict(
            scale=1.3,
        ),
        objaverse=dict(),
    ),
    mushroom=dict(
        types=("vegetable"),
        graspable=True,
        washable=True,
        microwavable=True,
        cookable=True,
        freezable=True,
        aigen=dict(
            scale=1.35,
        ),
        objaverse=dict(
            scale=1.20,
            exclude=[
                # "mushroom_16", # very very small holes. keeping anyway
            ],
        ),
    ),
    onion=dict(
        types=("vegetable"),
        graspable=True,
        washable=True,
        microwavable=True,
        cookable=True,
        freezable=False,
        aigen=dict(
            scale=1.1,
        ),
        objaverse=dict(),
    ),
    orange=dict(
        types=("fruit"),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=False,
        aigen=dict(
            scale=1.05,
        ),
        objaverse=dict(
            exclude=[
                # "orange_11", # bottom half is dark. keeping anyway
            ]
        ),
    ),
    pan=dict(
        types=("receptacle"),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=False,
        aigen=dict(
            scale=2.25,
        ),
        objaverse=dict(
            scale=1.70,
            exclude=[
                "pan_16",  # causing error. faces of mesh have inconsistent orientation,
                "pan_0",
                "pan_12",
                "pan_17",
                "pan_22",  # these are technically what we consider "pots"
            ],
        ),
    ),
    pot=dict(
        types=("receptacle"),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=False,
        aigen=dict(
            scale=2.25,
        ),
        objaverse=dict(
            model_folders=["objaverse/pan"],
            scale=1.70,
            exclude=list(
                set([f"pan_{i}" for i in range(25)])
                - set(["pan_0", "pan_12", "pan_17", "pan_22"])
            ),
        ),
    ),
    peach=dict(
        types=("fruit"),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=False,
        aigen=dict(
            scale=1.05,
        ),
        objaverse=dict(),
    ),
    pear=dict(
        types=("fruit"),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=False,
        aigen=dict(),
        objaverse=dict(
            exclude=[
                "pear_4",  # has big hole. excluding
            ]
        ),
    ),
    plate=dict(
        types=("receptacle"),
        graspable=False,
        washable=True,
        microwavable=True,
        cookable=False,
        freezable=False,
        aigen=dict(
            scale=1.65,
        ),
        objaverse=dict(
            scale=1.35,
            exclude=[
                "plate_6",  # causing error: faces of mesh have inconsistent orientation.
            ],
        ),
    ),
    potato=dict(
        types=("vegetable"),
        graspable=True,
        washable=True,
        microwavable=True,
        cookable=True,
        freezable=True,
        aigen=dict(
            scale=1.10,
        ),
        objaverse=dict(),
    ),
    rolling_pin=dict(
        types=("tool"),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=False,
        aigen=dict(
            scale=1.6,
        ),
        objaverse=dict(
            scale=1.25,
            exclude=[
                # "rolling_pin_5", # can see thru side handle edges, keeping anyway
                # "rolling_pin_1", # can see thru side handle edges, keeping anyway
            ],
        ),
    ),
    scissors=dict(
        types=("tool"),
        graspable=False,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=False,
        aigen=dict(
            scale=1.35,
        ),
        objaverse=dict(
            scale=1.15,
        ),
    ),
    shaker=dict(
        types=("condiment"),
        graspable=True,
        washable=False,
        microwavable=False,
        cookable=False,
        freezable=False,
        aigen=dict(
            scale=1.25,
        ),
        objaverse=dict(),
    ),
    soap_dispenser=dict(
        types=("cleaner"),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=False,
        aigen=dict(
            scale=1.7,
        ),
        objaverse=dict(
            exclude=[
                # "soap_dispenser_4", # can see thru body but that's fine if this is glass
            ]
        ),
    ),
    spatula=dict(
        types=("utensil"),
        graspable=False,
        washable=True,
        microwavable=False,
        cookable=True,
        freezable=False,
        aigen=dict(
            scale=1.30,
        ),
        objaverse=dict(
            scale=1.10,
        ),
    ),
    sponge=dict(
        types=("cleaner"),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=False,
        aigen=dict(
            scale=1.20,
        ),
        objaverse=dict(
            scale=0.90,
            # exclude=[
            #     "sponge_7", "sponge_1", # self turning due to single collision geom
            # ]
        ),
    ),
    spoon=dict(
        types=("utensil"),
        graspable=False,
        washable=True,
        microwavable=True,
        cookable=True,
        freezable=False,
        aigen=dict(
            scale=1.5,
        ),
        objaverse=dict(),
    ),
    spray=dict(
        types=("cleaner"),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=False,
        aigen=dict(
            scale=1.75,
        ),
        objaverse=dict(
            scale=1.75,
        ),
    ),
    squash=dict(
        types=("vegetable"),
        graspable=True,
        washable=True,
        microwavable=True,
        cookable=True,
        freezable=True,
        aigen=dict(
            scale=1.15,
        ),
        objaverse=dict(
            exclude=[
                "squash_10",  # hole at bottom
            ],
        ),
    ),
    steak=dict(
        types=("meat"),
        graspable=True,
        washable=True,
        microwavable=True,
        cookable=True,
        freezable=True,
        aigen=dict(
            scale=[1.0, 1.0, 2.0],
        ),
        objaverse=dict(
            scale=[1.0, 1.0, 2.0],
            exclude=[
                "steak_13",  # bottom texture completely messed up
                "steak_1",  # bottom texture completely messed up
                # "steak_9", # bottom with some minor issues, keeping anyway
            ],
        ),
    ),
    sweet_potato=dict(
        types=("vegetable"),
        graspable=True,
        washable=True,
        microwavable=True,
        cookable=True,
        freezable=True,
        aigen=dict(),
        objaverse=dict(),
    ),
    tangerine=dict(
        types=("fruit"),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=False,
        aigen=dict(),
        objaverse=dict(),
    ),
    teapot=dict(
        types=("receptacle"),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=False,
        aigen=dict(
            scale=1.25,
        ),
        objaverse=dict(
            scale=1.25,
            exclude=[
                "teapot_9",  # hole on bottom
            ],
        ),
    ),
    tomato=dict(
        types=("vegetable"),
        graspable=True,
        washable=True,
        microwavable=True,
        cookable=True,
        freezable=False,
        aigen=dict(
            scale=1.25,
        ),
        objaverse=dict(),
    ),
    tray=dict(
        types=("receptacle"),
        graspable=False,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=False,
        aigen=dict(scale=2.0),
        objaverse=dict(
            scale=1.80,
        ),
    ),
    waffle=dict(
        types=("sweets"),
        graspable=False,
        washable=False,
        microwavable=True,
        cookable=False,
        freezable=True,
        aigen=dict(
            scale=1.75,
        ),
        objaverse=dict(
            exclude=[
                "waffle_2",  # bottom completely messed up
            ]
        ),
    ),
    water_bottle=dict(
        types=("drink"),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=True,
        aigen=dict(
            scale=1.6,
        ),
        objaverse=dict(
            scale=1.5,
            exclude=[
                "water_bottle_11",  # sides and bottom see thru, but ok if glass. keeping anyway
            ],
        ),
    ),
    wine=dict(
        types=("drink", "alcohol"),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=False,
        aigen=dict(
            scale=1.9,
        ),
        objaverse=dict(
            scale=1.6,
            exclude=[
                "wine_7",  # causing error. faces of mesh have inconsistent orientation
            ],
        ),
    ),
    yogurt=dict(
        types=("dairy", "packaged_food"),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=True,
        aigen=dict(
            scale=1.0,
        ),
        objaverse=dict(
            scale=0.95,
        ),
    ),
    dates=dict(
        graspable=False,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=True,
        types=("fruit"),
        aigen=dict(),
    ),
    lemonade=dict(
        aigen=dict(
            scale=1.5,
        ),
        graspable=True,
        washable=False,
        microwavable=False,
        cookable=False,
        freezable=False,
        types=("drink"),
    ),
    walnut=dict(
        aigen=dict(
            scale=1.15,
        ),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=False,
        types=(),
    ),
    cheese_grater=dict(
        aigen=dict(
            scale=2.15,
        ),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=False,
        types=("tool"),
    ),
    syrup_bottle=dict(
        aigen=dict(
            scale=1.35,
        ),
        graspable=True,
        washable=False,
        microwavable=False,
        cookable=False,
        freezable=False,
        types=("condiment"),
    ),
    scallops=dict(
        aigen=dict(
            scale=1.25,
        ),
        graspable=True,
        washable=True,
        microwavable=True,
        cookable=True,
        freezable=True,
        types=("meat"),
    ),
    candy=dict(
        aigen=dict(),
        graspable=True,
        washable=False,
        microwavable=False,
        cookable=False,
        freezable=False,
        types=("sweets"),
    ),
    whisk=dict(
        aigen=dict(
            scale=1.8,
        ),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=False,
        types=("utensil"),
    ),
    pitcher=dict(
        aigen=dict(
            scale=1.75,
        ),
        graspable=True,
        washable=True,
        microwavable=True,
        cookable=False,
        freezable=False,
        types=("receptacle"),
    ),
    ice_cream=dict(
        aigen=dict(
            scale=1.25,
        ),
        graspable=True,
        washable=False,
        microwavable=False,
        cookable=False,
        freezable=True,
        types=("sweets"),
    ),
    cherry=dict(
        aigen=dict(),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=True,
        types=("fruit"),
    ),
    peanut_butter=dict(
        aigen=dict(
            scale=1.25,
            model_folders=["aigen_objs/peanut_butter_jar"],
        ),
        graspable=True,
        washable=False,
        microwavable=False,
        cookable=False,
        freezable=True,
        types=("packaged_food"),
    ),
    thermos=dict(
        aigen=dict(
            scale=1.75,
        ),
        graspable=True,
        washable=True,
        microwavable=True,
        cookable=False,
        freezable=True,
        types=("drink"),
    ),
    ham=dict(
        aigen=dict(
            scale=1.5,
        ),
        graspable=False,
        washable=True,
        microwavable=True,
        cookable=True,
        freezable=True,
        types=("meat"),
    ),
    dumpling=dict(
        aigen=dict(
            scale=1.15,
        ),
        graspable=True,
        washable=True,
        microwavable=True,
        cookable=True,
        freezable=True,
        types=("meat", "cooked_food"),
    ),
    cabbage=dict(
        aigen=dict(
            scale=2.0,
        ),
        graspable=False,
        washable=True,
        microwavable=False,
        cookable=True,
        freezable=True,
        types=("vegetable"),
    ),
    lettuce=dict(
        aigen=dict(
            scale=2.0,
        ),
        graspable=False,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=True,
        types=("vegetable"),
    ),
    tongs=dict(
        aigen=dict(
            scale=1.5,
        ),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=False,
        types=("tool"),
    ),
    ginger=dict(
        aigen=dict(
            scale=1.35,
        ),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=True,
        freezable=True,
        types=("vegetable"),
    ),
    ice_cube_tray=dict(
        aigen=dict(
            scale=2.0,
        ),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=True,
        types=("receptacle"),
    ),
    shrimp=dict(
        aigen=dict(
            scale=1.15,
        ),
        graspable=False,
        washable=True,
        microwavable=True,
        cookable=True,
        freezable=True,
        types=("meat"),
    ),
    cantaloupe=dict(
        aigen=dict(
            scale=1.5,
        ),
        graspable=False,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=True,
        types=("fruit"),
    ),
    honey_bottle=dict(
        aigen=dict(
            scale=1.10,
        ),
        graspable=True,
        washable=False,
        microwavable=False,
        cookable=False,
        freezable=True,
        types=("packaged_food"),
    ),
    grapes=dict(
        aigen=dict(
            scale=1.5,
        ),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=True,
        types=("fruit"),
    ),
    spaghetti_box=dict(
        aigen=dict(
            scale=1.25,
        ),
        graspable=False,
        washable=False,
        microwavable=False,
        cookable=False,
        freezable=False,
        types=("packaged_food"),
    ),
    chili_pepper=dict(
        aigen=dict(
            scale=1.10,
        ),
        graspable=True,
        washable=True,
        microwavable=True,
        cookable=True,
        freezable=True,
        types=("vegetable"),
    ),
    celery=dict(
        aigen=dict(
            scale=2.0,
        ),
        graspable=True,
        washable=True,
        microwavable=True,
        cookable=True,
        freezable=True,
        types=("vegetable"),
    ),
    burrito=dict(
        aigen=dict(
            scale=1.35,
        ),
        graspable=True,
        washable=False,
        microwavable=True,
        cookable=False,
        freezable=True,
        types=("cooked_food"),
    ),
    olive_oil_bottle=dict(
        aigen=dict(
            scale=1.5,
        ),
        graspable=True,
        washable=False,
        microwavable=False,
        cookable=False,
        freezable=True,
        types=("packaged_food"),
    ),
    kebabs=dict(
        aigen=dict(
            scale=1.65,
        ),
        graspable=True,
        washable=False,
        microwavable=True,
        cookable=True,
        freezable=True,
        types=("cooked_food"),
    ),
    bottle_opener=dict(
        aigen=dict(),
        graspable=False,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=True,
        types=("tool"),
    ),
    chicken_breast=dict(
        aigen=dict(
            scale=1.35,
        ),
        graspable=True,
        washable=True,
        microwavable=True,
        cookable=True,
        freezable=True,
        types=("meat"),
    ),
    jello_cup=dict(
        aigen=dict(
            scale=1.15,
        ),
        graspable=True,
        washable=False,
        microwavable=False,
        cookable=False,
        freezable=True,
        types=("packaged_food"),
    ),
    lobster=dict(
        aigen=dict(
            scale=1.15,
        ),
        graspable=True,
        washable=True,
        microwavable=True,
        cookable=True,
        freezable=True,
        types=("meat"),
    ),
    brussel_sprout=dict(
        aigen=dict(),
        graspable=True,
        washable=True,
        microwavable=True,
        cookable=True,
        freezable=True,
        types=("vegetable"),
    ),
    sushi=dict(
        aigen=dict(
            scale=0.90,
        ),
        graspable=True,
        washable=False,
        microwavable=False,
        cookable=False,
        freezable=True,
        types=("meat"),
    ),
    baking_sheet=dict(
        aigen=dict(
            scale=1.75,
        ),
        graspable=False,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=False,
        types=("receptacle"),
    ),
    wine_glass=dict(
        aigen=dict(
            scale=1.5,
        ),
        graspable=True,
        washable=True,
        microwavable=True,
        cookable=False,
        freezable=True,
        types=("receptacle"),
    ),
    asparagus=dict(
        aigen=dict(
            scale=1.35,
        ),
        graspable=True,
        washable=True,
        microwavable=True,
        cookable=True,
        freezable=True,
        types=("vegetable"),
    ),
    lamb_chop=dict(
        aigen=dict(
            scale=1.15,
        ),
        graspable=True,
        washable=True,
        microwavable=True,
        cookable=True,
        freezable=True,
        types=("meat"),
    ),
    pickle=dict(
        aigen=dict(
            scale=1.0,
        ),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=True,
        types=("vegetable"),
    ),
    bacon=dict(
        aigen=dict(
            scale=1.35,
        ),
        graspable=False,
        washable=False,
        microwavable=True,
        cookable=True,
        freezable=False,
        types=("meat"),
    ),
    canola_oil=dict(
        aigen=dict(
            scale=1.75,
        ),
        graspable=True,
        washable=False,
        microwavable=False,
        cookable=False,
        freezable=False,
        types=("packaged_food"),
    ),
    strawberry=dict(
        aigen=dict(
            scale=0.9,
        ),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=True,
        types=("fruit"),
    ),
    watermelon=dict(
        aigen=dict(
            scale=2.5,
        ),
        graspable=False,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=False,
        types=("fruit"),
    ),
    pizza_cutter=dict(
        aigen=dict(
            scale=1.4,
        ),
        graspable=False,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=False,
        types=("tool"),
    ),
    pomegranate=dict(
        aigen=dict(
            scale=1.25,
        ),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=False,
        types=("fruit"),
    ),
    apricot=dict(
        aigen=dict(
            scale=0.7,
        ),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=False,
        types=("fruit"),
    ),
    beet=dict(
        aigen=dict(),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=True,
        freezable=False,
        types=("vegetable"),
    ),
    radish=dict(
        aigen=dict(
            scale=1.0,
        ),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=False,
        types=("vegetable"),
    ),
    salsa=dict(
        aigen=dict(
            scale=1.15,
        ),
        graspable=True,
        washable=False,
        microwavable=False,
        cookable=False,
        freezable=False,
        types=("packaged_food"),
    ),
    artichoke=dict(
        aigen=dict(
            scale=1.35,
        ),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=True,
        freezable=False,
        types=("vegetable"),
    ),
    scone=dict(
        aigen=dict(
            scale=1.35,
        ),
        graspable=True,
        washable=False,
        microwavable=False,
        cookable=False,
        freezable=False,
        types=("pastry", "bread_food"),
    ),
    hamburger=dict(
        aigen=dict(
            scale=1.35,
        ),
        graspable=True,
        washable=False,
        microwavable=True,
        cookable=False,
        freezable=False,
        types=("cooked_food"),
    ),
    raspberry=dict(
        aigen=dict(
            scale=0.85,
        ),
        graspable=False,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=True,
        types=("fruit"),
    ),
    tacos=dict(
        aigen=dict(
            scale=1.0,
        ),
        graspable=True,
        washable=False,
        microwavable=True,
        cookable=False,
        freezable=False,
        types=("cooked_food"),
    ),
    vinegar=dict(
        aigen=dict(
            scale=1.4,
        ),
        graspable=True,
        washable=False,
        microwavable=False,
        cookable=False,
        freezable=False,
        types=("packaged_food", "condiment"),
    ),
    zucchini=dict(
        aigen=dict(
            scale=1.35,
        ),
        graspable=True,
        washable=True,
        microwavable=True,
        cookable=True,
        freezable=True,
        types=("vegetable"),
    ),
    pork_loin=dict(
        aigen=dict(),
        graspable=True,
        washable=True,
        microwavable=True,
        cookable=True,
        freezable=True,
        types=("meat"),
    ),
    pork_chop=dict(
        aigen=dict(
            scale=1.25,
        ),
        graspable=True,
        washable=True,
        microwavable=True,
        cookable=True,
        freezable=True,
        types=("meat"),
    ),
    sausage=dict(
        aigen=dict(
            scale=1.45,
        ),
        graspable=True,
        washable=True,
        microwavable=True,
        cookable=True,
        freezable=True,
        types=("meat"),
    ),
    coconut=dict(
        aigen=dict(
            scale=2.0,
        ),
        graspable=False,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=False,
        types=("fruit"),
    ),
    cauliflower=dict(
        aigen=dict(
            scale=1.5,
        ),
        graspable=False,
        washable=True,
        microwavable=True,
        cookable=True,
        freezable=True,
        types=("vegetable"),
    ),
    lollipop=dict(
        aigen=dict(),
        graspable=False,
        washable=False,
        microwavable=False,
        cookable=False,
        freezable=False,
        types=("sweets"),
    ),
    salami=dict(
        aigen=dict(
            scale=1.5,
        ),
        graspable=True,
        washable=True,
        microwavable=True,
        cookable=True,
        freezable=True,
        types=("meat"),
    ),
    butter_stick=dict(
        aigen=dict(
            scale=1.3,
        ),
        graspable=True,
        washable=False,
        microwavable=True,
        cookable=True,
        freezable=True,
        types=("dairy"),
    ),
    can_opener=dict(
        aigen=dict(
            scale=1.5,
        ),
        graspable=False,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=False,
        types=("tool"),
    ),
    tofu=dict(
        aigen=dict(),
        graspable=True,
        washable=True,
        microwavable=False,
        cookable=True,
        freezable=True,
        types=(),
    ),
    pineapple=dict(
        aigen=dict(
            scale=2.0,
        ),
        graspable=False,
        washable=True,
        microwavable=False,
        cookable=False,
        freezable=True,
        types=("fruit"),
    ),
    skewers=dict(
        aigen=dict(
            scale=1.75,
        ),
        graspable=True,
        washable=True,
        microwavable=True,
        cookable=True,
        freezable=False,
        types=("meat", "cooked_food"),
    ),
)


def get_cats_by_type(types, obj_registries=None):
    """
    Retrieves a list of item keys from the global `OBJ_CATEGORIES` dictionary based on the specified types.

    Args:
        types (list): A list of valid types to filter items by. Only items with a matching type will be included.
        obj_registries (list): only consider categories belonging to these object registries

    Returns:
        list: A list of keys from `OBJ_CATEGORIES` where the item's types intersect with the provided `types`.
    """
    types = set(types)

    res = []
    for key, val in OBJ_CATEGORIES.items():
        # check if category is in one of valid object registries
        if obj_registries is not None:
            if isinstance(obj_registries, str):
                obj_registries = [obj_registries]
            if any([reg in val for reg in obj_registries]) is False:
                continue

        if "types" in val:
            cat_types = val["types"]
        else:
            cat_types = list(val.values())[0].types
        if isinstance(cat_types, str):
            cat_types = [cat_types]
        cat_types = set(cat_types)
        # Access the "types" key in the dictionary using the correct syntax
        if len(cat_types.intersection(types)) > 0:
            res.append(key)

    return res


### define all object categories ###
OBJ_GROUPS = dict(
    all=list(OBJ_CATEGORIES.keys()),
)

for k in OBJ_CATEGORIES:
    OBJ_GROUPS[k] = [k]

all_types = set()
# populate all_types
for (cat, cat_meta_dict) in OBJ_CATEGORIES.items():
    # types are common to both so we only need to examine one
    cat_types = cat_meta_dict["types"]
    if isinstance(cat_types, str):
        cat_types = [cat_types]
    all_types = all_types.union(cat_types)

for t in all_types:
    OBJ_GROUPS[t] = get_cats_by_type(types=[t])

OBJ_GROUPS["food"] = get_cats_by_type(
    [
        "vegetable",
        "fruit",
        "sweets",
        "dairy",
        "meat",
        "bread_food",
        "pastry",
        "cooked_food",
    ]
)
OBJ_GROUPS["in_container"] = get_cats_by_type(
    [
        "vegetable",
        "fruit",
        "sweets",
        "dairy",
        "meat",
        "bread_food",
        "pastry",
        "cooked_food",
    ]
)

# custom groups
OBJ_GROUPS["container"] = ["plate"]  # , "bowl"]
OBJ_GROUPS["kettle"] = ["kettle_electric", "kettle_non_electric"]
OBJ_GROUPS["cookware"] = ["pan", "pot", "kettle_non_electric"]
OBJ_GROUPS["pots_and_pans"] = ["pan", "pot"]
OBJ_GROUPS["food_set1"] = [
    "apple",
    "baguette",
    "banana",
    "carrot",
    "cheese",
    "cucumber",
    "egg",
    "lemon",
    "orange",
    "potato",
]
OBJ_GROUPS["group1"] = ["apple", "carrot", "banana", "bowl", "can"]
OBJ_GROUPS["container_set2"] = ["plate", "bowl"]
